<?php

namespace beObject\MVC;

use beObject\Object;
use beObject\Primitive\String;
use beObject\Utils\ArrayList;
use beObject\Exceptions\FileNotFoundException;

/**
 * This object is the model of the MVC.<br />
 * This class contains all generics methods.
 * @author Dany Mottier
 * @copyright MD Consult
 * @license http://www.gnu.org/licenses/gpl.html
 * @link http://www.beobject-framework.net/beobject/mvc/model/model-class/<br />
 * @package beObject\MVC
 * @version 3.0
 * @abstract This class must be inherited.
 */
abstract class Model
    extends Object {

  /**
   * This arraylist will contains a collection of instance of the current class.
   * @var \beObject\Utils\ArrayList The $items collection allows user to store many typed
   * objects and can iterate on it.
   */
  public $items = null;

  /**
   * Instantiate the object and the encapsulated arraylist.
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-__construct/
   */
  public function __construct() {
    $this->items = new ArrayList();
  }

  /**
   * Build the object with a row.<br />
   * This row can be obtained by a call to SQL::FetchAssoc() or an array.<br />
   * You can also redefine this function to parse the row in another way.
   * @param array $array The row usually obtained by a call to MsSQL::fetchAssoc().
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-load/
   */
  public static function load($array) {
    $classname = get_called_class();
    $object = new $classname();

    foreach ($array as $key => $value) {
      if ($value == null) {
        $value = "";
      }

      if (is_callable(array($object, "set" . ucfirst($key)))) {
        $object->{"set" . ucfirst($key)}($value);
      }
    }
    return $object;
  }

  /**
   * Returns the object serialized.
   * @return beObject\Primitive\String The serialized object.
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-serialize/
   */
  public function serialize() {
    return new String(serialize($this));
  }

  /**
   * Rebuild the object from a serialized one.
   * @return \beObject\MVC\Model Returns the unserialized extended object.
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-unserialize/
   */
  public static function unserialize(String $string) {
    return unserialize(urldecode($string()));
  }

  /**
   * Serialize the current object and save the obtained string to a file.
   * @param beObject\Primitive\String $filename The filename you want to use.<br />
   * The extension is automatically added with ".sob" (for Serialized OBject).
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-savetofile/
   */
  public function saveToFile(String $filename) {
    $fp = fopen($filename->toString() . ".sob", "w");

    if ($fp) {
      fwrite($fp, $this->serialize());
      fclose($fp);
    }
  }

  /**
   * Rebuild the current object from a file.<br />
   * The file is obtained by a call to Model::saveToFile().
   * @param beObject\Primitive\String $filename The filename to load.<br />
   * Note that the extension is automatically added with ".sob" (for Serialized OBject).
   * @link http://www.beobject-framework.net/beobject/mvc/model/model-loadfromfile/
   */
  public static function loadFromFile(String $filename) {
    $f = new String($filename() . ".sob");
    if (file_exists($f())) {
      return Model::unserialize(new String(file_get_contents($f())));
    } else {
      throw new FileNotFoundException("The file '" . $f() . "' was not found.");
    }
  }

}

?>
